package top.szhome.develop.generator;

import lombok.Getter;
import top.szhome.framework.core.tools.exception.SzhomeException;
import top.szhome.framework.core.tools.util.StringUtil;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件系统
 *
 * @author 唐加利
 * @date 2023/9/6
 **/
public class FileSystem {

    /**
     * 跟节点目录
     */
    @Getter
    private List<FileNode> root = new LinkedList<>();

    /**
     * 创建目录
     * @param file
     */
    public FileNode mkdirs(String file) {
        return addNode(file, null);
    }

    /**
     * 创建文件
     * @param file
     * @param content
     * @return
     */
    public FileNode createFile(String file, String content) {
        if(content == null){
            throw new SzhomeException("文件内容不能为空");
        }

        return addNode(file, content);
    }

    /**
     * 创建文件
     * @param file
     * @param content
     */
    private FileNode addNode(String file, String content) {
        String[] paths = file.split(File.separator, -1);
        int len = paths.length;

        // 当前层级节点
        List<FileNode> nodes = root;
        FileNode parent = null;

        for(int i = 0; i < len; i++){
            String dir = paths[i];
            if(StringUtil.isBlank(dir)){
                continue;
            }

            // 目录是否存在
            Optional<FileNode> current = nodes.stream()
                    .filter(node -> node.getName().equals(dir))
                    .findFirst();

            // 创建当前节点
            String path = parent == null ? dir : (parent.getPath() + File.separator + dir);
            FileNode node = current.orElse(new FileNode(path, dir));
            if(!current.isPresent()){
                nodes.add(node);
                // 新增节点排序
                Collections.sort(nodes);
            }

            // 最后一个节点，设置文件内容
            if(i == len - 1 && content != null){
                node.setLeaf(true);
                node.setContent(content);
                return node;
            }

            // 调整层级，准备处理下一层
            nodes = node.getChildren();
            parent = node;
        }

        return null;
    }

    /**
     * 转压缩文件
     * @param os
     * @throws IOException
     */
    public void zip(OutputStream os) throws IOException {
        ZipOutputStream zip = new ZipOutputStream(os);
        for(FileNode node : root) {
            zip(zip, node);
        }
        zip.close();
    }

    /**
     * 递归转压缩文件
     * @param zip
     * @param node
     * @throws IOException
     */
    private void zip(ZipOutputStream zip, FileNode node) throws IOException {
        if(!node.isLeaf()){
            for(FileNode child : node.getChildren()){
                zip(zip, child);
            }
            return;
        }
        ZipEntry entry = new ZipEntry(node.getPath());
        zip.putNextEntry(entry);
        zip.write(node.getContent().getBytes(StandardCharsets.UTF_8));
        zip.closeEntry();
    }

    /**
     * 打印文件树
     */
    public void print(){
        print(root, 0);
    }

    /**
     * 递归打印文件树
     * @param nodes
     * @param level
     */
    private void print(List<FileNode> nodes, int level){
        Collections.sort(nodes);
        for(FileNode node : nodes){
            System.out.println(StringUtil.repeat(' ', 4 * level) +  (node.isLeaf() ? 'F' : 'D') + " " + node.getName());
            print(node.getChildren(), level + 1);
        }
    }


}
